<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>项目管理 - TechFolio 个人项目展示网站</title>
    <link rel="stylesheet" href="/css/element-ui.css">
    <link rel="stylesheet" href="/css/common.css">
    <script src="/js/vue.js"></script>
    <script src="/js/element-ui.js"></script>
    <script src="/js/axios.min.js"></script>
    <script src="/js/qs.js"></script>
</head>
<body>
<div id="app">
    <el-container>
        <!-- 头部 -->
        <el-header class="layout-header" style="">
            <div class="title">
                <h1>TechFolio 个人项目展示网站 v1.0.0</h1>
            </div>
            <el-breadcrumb separator-class="el-icon-arrow-right"
                           style="height: 48px; line-height: 48px; font-size: 16px;">
                <el-breadcrumb-item>后台管理</el-breadcrumb-item>
                <el-breadcrumb-item>项目管理</el-breadcrumb-item>
            </el-breadcrumb>
        </el-header>
        <!-- 主体 -->
        <el-container class="layout-body">
            <!-- 左侧 -->
            <el-aside width="80px" class="layout-aside">
                <div class="menu-item">
                    <a href="profile.html">
                        <div><i class="el-icon-user"></i></div>
                        <div class="menu-item-text">个人资料</div>
                    </a>
                </div>
                <div class="menu-item">
                    <a href="project.html" class="active">
                        <div><i class="el-icon-document-copy"></i></div>
                        <div class="menu-item-text">项目管理</div>
                    </a>
                </div>
                <div class="menu-item">
                    <a href="security.html">
                        <div><i class="el-icon-lock"></i></div>
                        <div class="menu-item-text">账号安全</div>
                    </a>
                </div>
                <div class="menu-item">
                    <a @click="logout">
                        <div><i class="el-icon-switch-button"></i></div>
                        <div class="menu-item-text">退出登录</div>
                    </a>
                </div>
            </el-aside>
            <!-- 右侧 -->
            <el-main class="layout-main">
                <!-- 操作区域 -->
                <div class="operate-area">
                    <div class="right">
                        <el-button type="primary" size="medium" style="float: right" @click="showAddNewForm">新增
                        </el-button>
                    </div>
                    <h1>项目管理</h1>
                </div>
                <!-- 数据表格 -->
                <el-table :data="tableData" style="width: 100%" header-cell-class-name="table-header">
                    <el-table-column prop="id" label="ID" width="60" align="center" fixed></el-table-column>
                    <el-table-column prop="name" label="名称" width="180" header-align="center" fixed></el-table-column>
                    <el-table-column label="封面" width="180" header-align="center">
                        <template slot-scope="scope">
                            <el-image style="width: 160px; height: 90px; border: 1px solid #c8c9cc; border-radius: 5px;"
                                      :src="scope.row.coverRemoteUrl"></el-image>
                        </template>
                    </el-table-column>
                    <el-table-column prop="startDate" label="开始日期" width="90" align="center"></el-table-column>
                    <el-table-column label="结束日期" width="90" align="center">
                        <template slot-scope="scope">
                            {{ scope.row.endDate ? scope.row.endDate : '至今' }}
                        </template>
                    </el-table-column>
                    <el-table-column prop="tags" label="标签" width="160" header-align="center"></el-table-column>
                    <el-table-column prop="technologies" label="技术栈" width="160"
                                     header-align="center"></el-table-column>
                    <el-table-column prop="summary" label="简介" width="500" header-align="center"></el-table-column>
                    <el-table-column label="是否显示" width="100" align="center">
                        <template slot-scope="scope">
                            <el-switch
                                    @change="toggleDisplay(scope.row)"
                                    v-model="scope.row.isDisplay"
                                    :active-value="1"
                                    :inactive-value="0"
                                    active-color="#13ce66"
                                    inactive-color="#999">
                            </el-switch>
                        </template>
                    </el-table-column>
                    <el-table-column prop="sortOrder" label="排序序号" width="100" align="center"></el-table-column>
                    <el-table-column label="操作" align="center" width="100" fixed="right">
                        <template slot-scope="scope">
                            <el-button type="primary" icon="el-icon-edit" size="mini" circle
                                       @click="showEditForm(scope.row)"></el-button>
                            <el-button type="danger" icon="el-icon-delete" size="mini" circle
                                       @click="openDeleteConfirm(scope.row)"></el-button>
                        </template>
                    </el-table-column>
                </el-table>
            </el-main>
        </el-container>

        <!-- 表单抽屉 -->
        <el-drawer
                :title="drawerTitle"
                :visible.sync="drawerVisibility"
                size="55%"
                destroy-on-close
                direction="rtl">
            <div style="padding-right: 30px;">
                <el-form :model="ruleForm" ref="ruleForm" label-width="100px" class="demo-ruleForm">
                    <el-form-item label="封面图">
                        <div class="simple-upload">
                            <div class="upload-control">
                                <i class="el-icon-plus" @click="uploadDialog.visible = true"></i>
                            </div>
                            <div class="image-preview" v-if="ruleForm.coverRemoteUrl">
                                <el-image :src="ruleForm.coverRemoteUrl" fit="cover" class="image"></el-image>
                                <div class="overlay">
                                    <div class="button-list">
                                        <i class="el-icon-refresh" @click="uploadDialog.visible = true"></i>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </el-form-item>
                    <el-form-item label="名称">
                        <el-input v-model="ruleForm.name" placeholder="请输入项目名称" maxlength="32"
                                  show-word-limit></el-input>
                    </el-form-item>
                    <el-row :gutter="20">
                        <el-col :span="12">
                            <el-form-item label="开始日期">
                                <el-date-picker v-model="ruleForm.startDate" type="date" value-format="yyyy-MM-dd"
                                                placeholder="请选择开始日期">
                                </el-date-picker>
                            </el-form-item>
                        </el-col>
                        <el-col :span="12">
                            <el-form-item label="结束日期">
                                <el-date-picker v-model="ruleForm.endDate" type="date" value-format="yyyy-MM-dd"
                                                placeholder="请选择结束日期">
                                </el-date-picker>
                            </el-form-item>
                        </el-col>
                    </el-row>
                    <el-form-item label="排序序号">
                        <el-input-number v-model="ruleForm.sortOrder" :min="1" :max="100"
                                         label="请输入排序序号"></el-input-number>
                    </el-form-item>
                    <el-form-item label="标签">
                        <el-input v-model="ruleForm.tags" placeholder="请输入项目标签，多个标签使用英文的逗号分隔"
                                  maxlength="50"
                                  show-word-limit></el-input>
                    </el-form-item>
                    <el-form-item label="技术栈">
                        <el-input v-model="ruleForm.technologies" placeholder="请输入项目技术栈" maxlength="150"
                                  show-word-limit></el-input>
                    </el-form-item>
                    <el-form-item label="简介">
                        <el-input type="textarea" v-model="ruleForm.summary" :rows="3" maxlength="150"
                                  show-word-limit></el-input>
                    </el-form-item>
                    <el-form-item label="详细描述">
                        <el-input type="textarea" v-model="ruleForm.details" :rows="8" maxlength="2000"
                                  show-word-limit></el-input>
                    </el-form-item>
                    <el-form-item label="是否显示" v-if="!isEditMode">
                        <el-switch
                                v-model="ruleForm.isDisplay"
                                :active-value="1"
                                :inactive-value="0"
                                active-color="#13ce66"
                                inactive-color="#999">
                        </el-switch>
                    </el-form-item>
                    <el-form-item>
                        <el-button type="primary" size="medium" @click="submitForm('ruleForm')">提交</el-button>
                        <el-button size="medium" @click="resetForm('ruleForm')">重置</el-button>
                    </el-form-item>
                </el-form>
                <!-- 弹出对话框：上传封面图 -->
                <el-dialog title="上传项目封面图" :visible.sync="uploadDialog.visible" width="35%" @open="clearPreview"
                           append-to-body>
                    <p>提示：建议上传宽高比为<span class="highlight-text">16:9</span>的图片，以达到最佳显示效果</p>
                    <el-upload
                            class="upload-demo"
                            action=""
                            :show-file-list="false"
                            :before-upload="beforeUpload"
                            :on-change="handleUploadChange">
                        <el-button size="small" type="primary">点击上传</el-button>
                    </el-upload>
                    <div>
                        <img v-if="uploadDialog.imageUrl" :src="uploadDialog.imageUrl"
                             style="width: 100%; height: 280px; object-fit: contain; margin-top: 10px;">
                    </div>
                    <div slot="footer" class="dialog-footer">
                        <el-button @click="uploadDialog.visible = false">取消</el-button>
                        <el-button type="primary" @click="submitUpload">提交</el-button>
                    </div>
                </el-dialog>
            </div>
        </el-drawer>
    </el-container>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            uploadDialog: {
                visible: false,
                imageUrl: '',
                file: null,
            },
            // 抽屉数据
            drawerTitle: '',
            drawerVisibility: false,
            isEditMode: false,
            // 表单数据
            ruleForm: {
                id: 0,
                coverImageId: '',
                coverRemoteUrl: '',
                name: '',
                startDate: '',
                endDate: '',
                sortOrder: 1,
                tags: '',
                technologies: '',
                summary: '',
                details: '',
                isDisplay: 0
            },
            // 表格数据
            tableData: [],
        },
        methods: {
            // 打开新增表单
            showAddNewForm() {
                this.resetForm();
                this.drawerTitle = '新增项目';
                this.drawerVisibility = true;
                this.isEditMode = false;
            },
            // 打开修改表单
            showEditForm(row) {
                this.ruleForm = {...row};
                this.drawerTitle = '修改项目';
                this.drawerVisibility = true;
                this.isEditMode = true;
            },
            // 切换显示状态
            toggleDisplay(row) {
                let url = '/api/project/' + row.id + '/toggle-display';
                let params = 'isDisplay=' + row.isDisplay;
                axios.post(url, params).then(response => {
                    let jsonResult = response.data;
                    if (jsonResult.state === 20000) {
                        this.$message({
                            type: 'success',
                            message: '操作成功'
                        });
                    } else if (jsonResult.state === 40100) {
                        this.$alert(jsonResult.message, '错误', {
                            confirmButtonText: '确定',
                            callback: action => {
                                window.location.href = 'login.html';
                            }
                        });
                    } else {
                        this.$alert(jsonResult.message, '错误', {
                            confirmButtonText: '确定',
                            callback: action => {
                            }
                        });
                    }
                }).catch(error => {
                    this.$alert('服务器端无法正确响应【切换项目显示状态】功能！', '错误', {
                        confirmButtonText: '确定',
                        callback: action => {
                        }
                    });
                });
            },
            // 打开删除确认框
            openDeleteConfirm(row) {
                let message = '将删除【' + row.name + '】数据，将不可恢复，是否继续？';
                this.$confirm(message, '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    this.handleDelete(row);
                }).catch(() => {
                });
            },
            // 处理删除
            handleDelete(row) {
                let url = '/api/project/' + row.id + '/delete'
                axios.post(url).then(response => {
                    let jsonResult = response.data;
                    if (jsonResult.state === 20000) {
                        this.$message({
                            type: 'success',
                            message: '操作成功'
                        });
                    } else if (jsonResult.state === 40100) {
                        this.$alert(jsonResult.message, '错误', {
                            confirmButtonText: '确定',
                            callback: action => {
                                window.location.href = 'login.html';
                            }
                        });
                    } else {
                        this.$alert(jsonResult.message, '错误', {
                            confirmButtonText: '确定',
                            callback: action => {
                            }
                        });
                    }
                    this.loadProjectList();
                }).catch(error => {
                    this.$alert('服务器端无法正确响应【删除项目】功能！', '错误', {
                        confirmButtonText: '确定',
                        callback: action => {
                        }
                    });
                });
            },
            // 提交抽屉中的表单
            submitForm(formName) {
                this.$refs[formName].validate((valid) => {
                    if (valid) {
                        let url = '/api/project/';
                        if (this.isEditMode) {
                            url += this.ruleForm.id + '/update';
                        } else {
                            url += 'add-new';
                        }

                        let formattedStartDate = this.ruleForm.startDate;
                        if (formattedStartDate.length === 7) { // yyyy-MM 格式
                            formattedStartDate = formattedStartDate + '-01';
                        }
                        this.ruleForm.startDate = new Date(formattedStartDate).toISOString().split('T')[0];

                        let formData = Qs.stringify(this.ruleForm);
                        axios.post(url, formData).then(response => {
                            let jsonResult = response.data;
                            if (jsonResult.state === 20000) {
                                this.$message({
                                    type: 'success',
                                    message: '操作成功'
                                });
                                this.drawerVisibility = false;
                            } else if (jsonResult.state === 40100) {
                                this.$alert(jsonResult.message, '错误', {
                                    confirmButtonText: '确定',
                                    callback: action => {
                                        window.location.href = 'login.html';
                                    }
                                });
                            } else {
                                this.$alert(jsonResult.message, '错误', {
                                    confirmButtonText: '确定',
                                    callback: action => {
                                    }
                                });
                            }
                            this.loadProjectList();
                        }).catch(error => {
                            this.$alert('服务器端无法正确响应【提交项目】功能！', '错误', {
                                confirmButtonText: '确定',
                                callback: action => {
                                }
                            });
                        });
                    } else {
                        this.$alert('请正确填写数据！', '错误', {
                            confirmButtonText: '确定',
                            callback: action => {
                            }
                        });
                        return false;
                    }
                });
            },
            // 清除对话框中的预览图
            clearPreview() {
                this.uploadDialog.imageUrl = '';
                this.uploadDialog.file = null;
            },
            // 删除图片
            removeCoverImage() {
                this.ruleForm.coverImageId = '';
                this.ruleForm.coverRemoteUrl = '';
            },
            handleUploadChange(file) {
                this.uploadDialog.file = file;
                this.uploadDialog.imageUrl = URL.createObjectURL(file.raw);
            },
            beforeUpload(file) {
                const isJPG = file.type === 'image/jpeg';
                const isPNG = file.type === 'image/png';
                const isLt10M = file.size / 1024 / 1024 < 10;

                if (!isJPG && !isPNG) {
                    this.$message.error('照片只能是 JPG/PNG 格式!');
                }
                if (!isLt10M) {
                    this.$message.error('照片大小不能超过 10MB!');
                }
                return (isJPG || isPNG) && isLt10M;
            },
            // 上传图片
            submitUpload() {
                if (!this.uploadDialog.file) {
                    this.$message.error('请先选择图片');
                    return;
                }
                let url = '/api/image/upload';

                let formData = new FormData();
                formData.append('file', this.uploadDialog.file.raw);
                formData.append('imageType', 1);

                axios.post(url, formData, {
                    headers: {
                        'Content-Type': 'multipart/form-data'
                    }
                }).then(response => {
                    let jsonResult = response.data;
                    if (jsonResult.state === 20000) {
                        this.ruleForm.coverImageId = jsonResult.data.id;
                        this.ruleForm.coverRemoteUrl = jsonResult.data.remoteUrl;
                        this.$message.success('上传封面图片成功');
                        this.uploadDialog.visible = false;
                    } else if (jsonResult.state === 40100) {
                        this.$alert(jsonResult.message, '错误', {
                            confirmButtonText: '确定',
                            callback: action => {
                                window.location.href = 'login.html';
                            }
                        });
                    } else {
                        this.$alert(jsonResult.message, '错误', {
                            confirmButtonText: '确定',
                            callback: action => {
                            }
                        });
                    }
                }).catch(error => {
                    this.$alert('服务器端无法正确响应【上传图片】功能！', '错误', {
                        confirmButtonText: '确定',
                        callback: action => {
                        }
                    });
                });
            },
            // 重置抽屉中的表单
            resetForm() {
                this.ruleForm.name = '';
                this.ruleForm.coverImageId = '';
                this.ruleForm.coverRemoteUrl = '';
                this.ruleForm.startDate = '';
                this.ruleForm.endDate = '';
                this.ruleForm.sortOrder = 1;
                this.ruleForm.tags = '';
                this.ruleForm.technologies = '';
                this.ruleForm.summary = '';
                this.ruleForm.details = '';
                this.ruleForm.isDisplay = 0;
            },
            // 加载项目列表
            loadProjectList() {
                let url = '/api/project/list';
                axios.get(url).then(response => {
                    let jsonResult = response.data;
                    if (jsonResult.state == 20000) {
                        this.tableData = jsonResult.data;
                    } else if (jsonResult.state === 40100) {
                        this.$alert(jsonResult.message, '错误', {
                            confirmButtonText: '确定',
                            callback: action => {
                                window.location.href = 'login.html';
                            }
                        });
                    } else {
                        this.$alert(jsonResult.message, '错误', {
                            confirmButtonText: '确定',
                            callback: action => {
                            }
                        });
                    }
                }).catch(error => {
                    this.$alert('服务器端无法正确响应【加载项目列表】功能！', '错误', {
                        confirmButtonText: '确定',
                        callback: action => {
                        }
                    });
                });
            },
            // 退出登录
            logout() {
                let message = '登录信息将被注销，在重新登录之前不可进行后台管理操作，是否继续？';
                this.$confirm(message, '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    let url = '/api/admin/logout';
                    axios.post(url).then(response => {
                        let jsonResult = response.data;
                        if (jsonResult.state === 20000) {
                            window.location.href = '/';
                        } else {
                            this.$alert(jsonResult.message, '错误', {
                                confirmButtonText: '确定',
                                callback: action => {
                                    window.location.href = 'login.html';
                                }
                            });
                        }
                    }).catch(error => {
                        this.$alert('服务器端无法正确响应【退出登录】功能！', '错误', {
                            confirmButtonText: '确定',
                            callback: action => {
                            }
                        });
                    });
                }).catch(() => {
                });
            }
        },
        mounted() {
            this.loadProjectList();
        }
    });
</script>
</body>
</html>